<template>
    <view
        class="flex-box bg-black-op005 justify-center align-item-center"
        v-if="sw"
        :style="'width:' + sw + 'px;height:' + sh + 'px;'"
        @click="
            () => {
                exit = false;
            }
        "
    >
        <view
            :style="
                'width:' +
                (cropW + 6) +
                'px;height: ' +
                (cropH + 6) +
                'px;padding:3px;border: rgba(0,0,0,0.1) 1px solid;border-radius:' +
                20 * OUTP * 2 +
                'px'
            "
            class="flex-box justify-center box-shadow-gray flex-direction-column align-item-center"
        >
            <view
                class="flex-box justify-center box-sizing bg-white-main flex-direction-column align-item-center"
                :style="
                    'border: rgba(250,96,68,0.5) 1px solid;width: 100%;height:100%;border-radius:' +
                    20 * OUTP * 2 +
                    'px'
                "
                @click.stop="chooseImg"
            >
                <text
                    v-if="!bgImgObj.path"
                    class="text-main text-bold"
                    style="font-size: 80rpx"
                    >+</text
                >
                <text
                    v-if="!bgImgObj.path"
                    class="margin-top-50 text-main text-32"
                    >上传图片</text
                >
            </view>
        </view>
        <view
            class="po-fixd over-hidden"
            v-if="bgImgObj.path"
            @click.stop="
                () => {
                    exit = true;
                }
            "
            :style="
                'left:' +
                (centerX - cropW / 2) +
                'px;top:' +
                (centerY - cropH / 2) +
                'px;width:' +
                cropW +
                'px;height:' +
                cropH +
                'px;border-radius:' +
                20 * OUTP * 2 +
                'px;'
            "
        >
            <image
                :src="bgImgObj.path"
                mode="scaleToFill"
                class="position-absolute"
                :class="bgImgObj.direction && 'rotatex'"
                :style="
                    'transform: rotate(' +
                    bgImgObj.angle +
                    'deg) ' +
                    (bgImgObj.direction ? 'matrix(-1,0,0,1,0,0);' : '') +
                    ';left:' +
                    (bgImgObj.x - centerX + cropW / 2) +
                    'px;top:' +
                    (bgImgObj.y - centerY + cropH / 2) +
                    'px;opacity: 1;vertical-align:top;width:' +
                    bgImgObj.w +
                    'px;height:' +
                    bgImgObj.h +
                    'px;border-radius:' +
                    20 * OUTP * 2 +
                    'px;'
                "
            >
            </image>
        </view>
        <!-- 移动 -->
        <view
            class="po-fixd"
            v-if="bgImgObj.path && exit"
            @touchstart.stop="fStart"
            @touchmove.stop="fMove"
            @touchend="fEnd"
            style="border: rgba(250, 96, 68, 1) 1px solid"
            :style="
                'transform: rotate(' +
                bgImgObj.angle +
                'deg);width:' +
                (bgImgObj.w + 20) +
                'px;height: ' +
                (bgImgObj.h + 20) +
                'px;left:' +
                (bgImgObj.x - 10) +
                'px;top:' +
                (bgImgObj.y - 10) +
                'px'
            "
        >
            <!-- 缩放 -->
            <view
                class="w48h48 position-absolute flex-box justify-center align-item-center bg-main radius50"
                @touchstart.stop="fStart"
                @touchmove.stop="scaleMove"
                @touchend.stop="scaleEnd"
                style="bottom: -24rpx; right: -24rpx"
            >
                <text class="text-20 text-white">缩</text>
            </view>
            <!-- 旋转 -->
            <view
                class="w48h48 position-absolute flex-box justify-center align-item-center bg-main radius50"
                @touchstart.stop="fStart"
                @touchmove.stop="xuanMove"
                style="top: -24rpx; right: -24rpx"
            >
                <text class="text-20 text-white">旋</text>
            </view>

            <view
                class="w48h48 position-absolute flex-box justify-center align-item-center bg-main radius50"
                @click.stop="
                    () => {
                        bgImgObj.direction = !bgImgObj.direction;
                    }
                "
                style="top: -24rpx; left: -24rpx; z-index: 1111"
            >
                <text class="text-20 text-white">反</text>
            </view>

            <!-- 更换图片 -->
            <view
                class="position-absolute flex-box justify-center align-item-center bg-main radius80"
                @click.stop="chooseImg"
                style="
                    top: -64rpx;
                    transform: translate(-50%);
                    left: 50%;
                    width: 120rpx;
                    height: 40rpx;
                "
            >
                <view
                    class="position-relative flex-box justify-center align-item-center"
                    style="width: 120rpx;40rpx"
                >
                    <text class="text-20 text-white">点击换图</text>
                </view>
            </view>
        </view>

        <view
            class="po-fixd vw100 padding-small bg-main flex-box justify-around box-shadow-gray box-sizing align-item-center"
            style="height: 50px; bottom: 0rpx; left: 0rpx"
            @click.stop="save"
        >
            <text class="text-32 text-white">完成</text>
        </view>

        <canvas
            :style="
                'width: ' +
                phonew +
                'px; height: ' +
                phoneh +
                'px;position: fixed;left:-3000px;top:0px'
            "
            canvas-id="firstCanvas"
            id="firstCanvas"
        ></canvas>
        <!-- 旋转 -->
        <canvas
            :style="
                'width: ' +
                bgImgc +
                'px; height: ' +
                bgImgc +
                'px;position: fixed;left:-3000px;top:0px'
            "
            canvas-id="bgImgc"
            id="bgImgc"
        ></canvas>
        <!-- 镜向 -->
        <canvas
            :style="
                'width: ' +
                bgImgObj.initw / OUTP +
                'px; height: ' +
                bgImgObj.inith / OUTP +
                'px;position: fixed;left:-3000px;top:0px'
            "
            canvas-id="left2right"
            id="left2right"
        ></canvas>
    </view>
</template>

<script>
let system = uni.getSystemInfoSync();
import { chooseImage } from "@/utils/utils";
export default {
    data() {
        return {
            OUTP: 0.5,
            exit: true,
            sw: "", //屏幕宽度
            sh: "", //屏幕高度
            centerX: "", //中心点
            centerY: "", //中心点
            bgImgObj: {
                path: "",
                x: "",
                y: "",
                w: "",
                h: "",
                initX: "", //初始位置
                initY: "", //初始位置
                initw: "",
                inith: "",
                direction: false, //图片取反
                angle: 0, //旋转角度
            },
            sx: "", //开始触模点X坐标
            sy: "", //开始触模点Y坐标
            mx: "", //移动中的x坐标
            my: "", //移动中的y坐标
            context: "",
            context2: "",
            context3: "",
        };
    },
    props: {
        phonew: {
            type: Number,
            default: 500,
        },
        phoneh: {
            type: Number,
            default: 500,
        },
    },
    computed: {
        cropW: function () {
            return this.phonew * this.OUTP;
        },
        cropH: function () {
            return this.phoneh * this.OUTP;
        },

        bgImgc: function () {
            return (
                Math.sqrt(
                    Math.pow(this.bgImgObj.w / (2 * this.OUTP), 2) +
                        Math.pow(this.bgImgObj.h / (2 * this.OUTP), 2)
                ) * 2
            );
        },
        imgcenterX: function () {
            return this.bgImgObj.x + this.bgImgObj.w / 2;
        },
        imgcenterY: function () {
            return this.bgImgObj.y + this.bgImgObj.h / 2;
        },
    },

    created() {
        let system = uni.getSystemInfoSync();
        this.sw = system.windowWidth;
        this.sh = system.windowHeight - 50; //减掉底部50px
        this.centerX = this.sw / 2;
        this.centerY = this.sh / 2;
    },
    mounted() {
        this.context = uni.createCanvasContext("firstCanvas");
        this.context2 = uni.createCanvasContext("bgImgc");
        this.context3 = uni.createCanvasContext("left2right");
    },

    methods: {
        chooseImg: function () {
            chooseImage({
                count: 1, //默认9
                sizeType: ["original"], //可以指定是原图还是压缩图，默认二者都有
                // sourceType: ['album'], //从相册选择
                success: (success) => {
                    console.log(success);
                    this.bgImg = success.tempFilePaths[0];
                    uni.getImageInfo({
                        src: success.tempFilePaths[0],
                        success: (info) => {
                            console.log(info);
                            if (
                                (this.cropW * info.height) / info.width <
                                this.cropH
                            ) {
                                this.bgImgObj = {
                                    path: info.path,
                                    initw:
                                        (this.cropH * info.width) / info.height,
                                    inith: this.cropH,
                                    w: (this.cropH * info.width) / info.height,
                                    h: this.cropH,
                                    x:
                                        this.centerX -
                                        (this.cropH * info.width) /
                                            info.height /
                                            2,
                                    y: this.centerY - this.cropH / 2,
                                    initX:
                                        this.centerX -
                                        (this.cropH * info.width) /
                                            info.height /
                                            2,
                                    initY: this.centerY - this.cropH / 2,
                                    direction: false,
                                    angle: 0,
                                };
                            } else if (
                                (this.cropW * info.height) / info.width >
                                this.cropH
                            ) {
                                this.bgImgObj = {
                                    path: info.path,
                                    initw: this.cropW,
                                    inith:
                                        (this.cropW * info.height) / info.width,
                                    w: this.cropW,
                                    h: (this.cropW * info.height) / info.width,
                                    x: this.centerX - this.cropW / 2,
                                    y:
                                        this.centerY -
                                        (this.cropW * info.height) /
                                            info.width /
                                            2,
                                    initX: this.centerX - this.cropW / 2,
                                    initY:
                                        this.centerY -
                                        (this.cropW * info.height) /
                                            info.width /
                                            2,
                                    direction: false,
                                    angle: 0,
                                };
                            } else {
                                this.bgImgObj = {
                                    path: info.path,
                                    initw: this.cropW,
                                    inith:
                                        (this.cropW * info.height) / info.width,
                                    w: this.cropW,
                                    h: (this.cropW * info.height) / info.width,
                                    x: this.centerX - this.cropW / 2,
                                    y: this.centerY - this.cropH / 2,
                                    initX: this.centerX - this.cropW / 2,
                                    initY: this.centerY - this.cropH / 2,
                                    direction: false,
                                    angle: 0,
                                };
                            }
                        },
                    });
                },
            });
        },
        fStart: function (e) {
            //移动
            this.sx = e.touches[0].pageX;
            this.sy = e.touches[0].pageY;
        },
        scaleMove: function (e) {
            this.mx = e.touches[0].pageX;
            this.my = e.touches[0].pageY;
            let movew = this.sx - this.mx; //负数
            let moveh = this.sy - this.my;

            this.bgImgObj.x = this.bgImgObj.x + movew;
            this.bgImgObj.y = this.bgImgObj.y + moveh;
            this.bgImgObj.w = this.bgImgObj.w - movew * 2;
            this.bgImgObj.h = this.bgImgObj.h - moveh * 2;
            this.sx = this.mx;
            this.sy = this.my;
        },
        //旋转
        xuanMove: function (e) {
            let radian = Math.atan(
                (this.imgcenterY - e.touches[0].pageY) /
                    (e.touches[0].pageX - this.imgcenterX)
            ); //弧度
            let angle = Math.floor(180 / (Math.PI / radian)); //弧度转角度
            if (e.touches[0].pageX - this.imgcenterX < 0) {
                //x小于0的时候加上180°，即实际角度
                angle = angle + 180;
            }
            this.bgImgObj.angle = 60 - angle;
        },
        fMove: function (e) {
            //移动
            if (e.touches.length == 1) {
                this.mx = e.touches[0].pageX;
                this.my = e.touches[0].pageY;

                this.bgImgObj.x = this.bgImgObj.x + (this.mx - this.sx);
                this.bgImgObj.y = this.bgImgObj.y + (this.my - this.sy);

                this.sx = this.mx;
                this.sy = this.my;
            }
        },
        fEnd: function (e) {
            //移动到方框内，恢复到之前的

            /* 当左上角和右下角坐标在方框内，恢复到之前的 */
            /* 左上角 */
            if (
                this.bgImgObj.x > this.centerX - this.cropW / 2 ||
                this.bgImgObj.y > this.centerY - this.cropH / 2
            ) {
                this.bgImgObj.x = this.centerX - this.bgImgObj.w / 2;
                this.bgImgObj.y = this.centerY - this.bgImgObj.h / 2;
                return;
            }
            /* 右上角 */
            if (
                this.bgImgObj.x + this.bgImgObj.w <
                this.centerX + this.cropW / 2
            ) {
                this.bgImgObj.x = this.centerX - this.bgImgObj.w / 2;
                this.bgImgObj.y = this.centerY - this.bgImgObj.h / 2;
                return;
            }

            /* 左下角 */
            if (
                this.bgImgObj.y + this.bgImgObj.h <
                this.centerY + this.cropH / 2
            ) {
                this.bgImgObj.x = this.centerX - this.bgImgObj.w / 2;
                this.bgImgObj.y = this.centerY - this.bgImgObj.h / 2;
                return;
            }
        },
        scaleEnd: function (e) {
            if (this.bgImgObj.w < this.cropW || this.bgImgObj.h < this.cropH) {
                //当宽度不够不让移动
                setTimeout((res) => {
                    this.bgImgObj.x = this.bgImgObj.initX;
                    this.bgImgObj.y = this.bgImgObj.initY;
                    this.bgImgObj.w = this.bgImgObj.initw;
                    this.bgImgObj.h = this.bgImgObj.inith;
                }, 100);
            }
        },
        save: function () {
            uni.showLoading({
                title: "请稍后",
                mask: true,
            });
            /* 	1.有水平翻转,有转动
	2.只有水平翻转
	3.只有转动
	4.只有缩放 不用处理 */
            if (this.bgImgObj.direction && this.bgImgObj.angle) {
                //有水平翻转 并且有转动
                this.left2rightimg2(
                    this.bgImgObj.path,
                    this.bgImgObj.initw / this.OUTP,
                    this.bgImgObj.initw / this.OUTP,
                    this.bgImgObj.inith / this.OUTP
                ).then((success) => {
                    this.rotateAngle(success).then((res) => {
                        this.scale(res).then((scale) => {
                            uni.hideLoading();
                            this.$emit("save", scale);
                        });
                    });
                });

                return;
            }
            //只有水平翻转
            if (this.bgImgObj.direction) {
                this.left2rightimg2(
                    this.bgImgObj.path,
                    this.bgImgObj.initw / this.OUTP,
                    this.bgImgObj.initw / this.OUTP,
                    this.bgImgObj.inith / this.OUTP
                ).then((success) => {
                    this.scale(success).then((scale) => {
                        uni.hideLoading();
                        this.$emit("save", scale);
                    });
                });
                return;
            }

            if (this.bgImgObj.angle) {
                this.rotateAngle(this.bgImgObj.path).then((res) => {
                    this.scale(res).then((scale) => {
                        uni.hideLoading();
                        this.$emit("save", scale);
                    });
                });
                return;
            }

            //只有缩放或没操作
            this.scale(this.bgImgObj.path).then((scale) => {
                uni.hideLoading();
                this.$emit("save", scale);
            });
        },
        //水平翻转
        left2rightimg2(file, canvasw, imgw, imgh) {
            return new Promise((resolve, reject) => {
                this.context3.save();
                this.context3.translate((canvasw - imgw * -1) / 2, 0);
                this.context3.scale(-1, 1);
                this.context3.drawImage(file, 0, 0, imgw, imgh);
                this.context3.restore();
                this.context3.draw(false, (res) => {
                    uni.canvasToTempFilePath({
                        canvasId: "left2right",
                        fileType: "png",
                        quality: 1,
                        success: (success) => {
                            resolve(success.tempFilePath);
                        },
                    });
                });
            });
        },
        //旋转
        rotateAngle: function (tempFilePath) {
            return new Promise((resolve, reject) => {
                this.context2.save();
                this.context2.translate(this.bgImgc / 2, this.bgImgc / 2);
                this.context2.rotate((this.bgImgObj.angle * Math.PI) / 180);
                this.context2.drawImage(
                    tempFilePath,
                    -this.bgImgObj.w / (2 * this.OUTP),
                    -this.bgImgObj.h / (2 * this.OUTP),
                    this.bgImgObj.w / this.OUTP,
                    this.bgImgObj.h / this.OUTP
                );
                this.context2.restore();
                this.context2.draw(false, (res) => {
                    uni.canvasToTempFilePath({
                        canvasId: "bgImgc",
                        fileType: "png",
                        quality: 1,
                        success: (success) => {
                            resolve(success.tempFilePath);
                        },
                    });
                });
            });
        },
        //缩放
        scale: function (tempFilePath) {
            return new Promise((resolve, reject) => {
                this.context.translate(0, 0);
                if (this.bgImgObj.angle) {
                    this.context.drawImage(
                        tempFilePath,
                        (this.bgImgObj.x - this.centerX + this.cropW / 2) /
                            this.OUTP -
                            (this.bgImgc / 2 -
                                this.bgImgObj.w / (2 * this.OUTP)),
                        (this.bgImgObj.y - this.centerY + this.cropH / 2) /
                            this.OUTP -
                            (this.bgImgc / 2 -
                                this.bgImgObj.h / (2 * this.OUTP)),
                        this.bgImgc,
                        this.bgImgc
                    );
                } else {
                    this.context.drawImage(
                        tempFilePath,
                        (this.bgImgObj.x - this.centerX + this.cropW / 2) /
                            this.OUTP,
                        (this.bgImgObj.y - this.centerY + this.cropH / 2) /
                            this.OUTP,
                        this.bgImgObj.w / this.OUTP,
                        this.bgImgObj.h / this.OUTP
                    );
                }

                this.context.draw(false, (res) => {
                    uni.canvasToTempFilePath({
                        canvasId: "firstCanvas",
                        destWidth: this.phonew,
                        destHeight: this.phoneh,
                        fileType: "png",
                        quality: 1,
                        success: (success) => {
                            resolve(success.tempFilePath);
                        },
                    });
                });
            });
        },
    },
};
</script>
<style>
.rotatex {
    transform: scaleX(-1);
}
.flex-box {
    display: flex;
}
.bg-black-op005 {
    background-color: rgba(0, 0, 0, 0.05);
}
.justify-center {
    justify-content: center;
}
.align-item-center {
    align-items: center;
}
.box-shadow-gray {
    box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3);
}
.flex-direction-column {
    flex-direction: column;
}
.box-sizing {
    box-sizing: border-box;
}
.bg-white-main {
    background-color: #ffffff;
}
.margin-top-50 {
    margin-top: 50rpx;
}
.po-fixd {
    position: fixed;
}
.over-hidden {
    overflow: hidden;
}
.position-absolute {
    position: absolute;
}
.w48h48 {
    width: 48rpx;
    height: 48rpx;
}
.bg-main {
    background-color: #fa6044;
}
.radius50 {
    border-radius: 50%;
}
.text-24 {
    font-size: 24rpx;
}
.text-white {
    color: #ffffff;
}
.text-28 {
    font-size: 28rpx;
}
.text-20 {
    font-size: 20rpx;
}
.triangle {
    width: 20rpx;
    height: 20rpx;
    position: relative;
    overflow: hidden;
}

.triangle:before {
    content: "";
    position: absolute;
    width: 20rpx;
    height: 20rpx;
    top: 0px;
    right: -13rpx;
    border-radius: 5rpx;
    background: #fa6044;
    transform: rotate(45deg);
}
.sbox-shadow {
    box-shadow: -1px -1px 5px rgba(0, 0, 0, 0.6);
}
.bg-white-main {
    background-color: #ffffff;
}
.vw100 {
    width: 100vw;
}
.padding-small {
    padding: 10rpx;
}
.justify-around {
    justify-content: space-around;
}
.bg-main-lever2 {
    background-color: rgba(250, 96, 68, 0.08);
}
.radius80 {
    border-radius: 80rpx;
}
</style>
